package eu.catengine.common.manager;

import java.io.IOException;
import java.util.HashMap;

import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import eu.catengine.audio.Audio;
import eu.catengine.common.iface.IDisposable;
import eu.catengine.common.iface.IManager;

/**
 * Manager odpowiedzialny za przechowywanie danych dzwięków.
 * 
 * @author mbienkowski
 */
public class AudioManager implements IDisposable, IManager<AudioManager, Audio>
{
    private static volatile AudioManager mInstance;
    private HashMap<String, Audio> mAudioHashMap;
    private AssetManager mAssetManager;

    private AudioManager()
    {
	mAudioHashMap = new HashMap<String, Audio>();
    }

    /**
     * Zwraca instanację managera.
     */
    public static AudioManager getInstance()
    {
	if (mInstance == null)
	{
	    mInstance = new AudioManager();
	}
	return mInstance;
    }

    /**
     * Ustawia managera zasobów zewnętrznych dla managera.<br>
     * Metoda wywoływana automatycznie.
     */
    public void setAssetManager(AssetManager assetManager)
    {
	this.mAssetManager = assetManager;
    }

    /**
     * Ładuje dźwięk do managera.
     * <br>
     * Po wczytaniu odwołujemy się do obiektu po jego nazwie, bez rozszerzenia.
     * @param pathName
     *            <code>String</code> Ścieżka pliku z katalogu "Assets/"
     * @return <code>Audio</code> zwraca stworzony obiekt.
     */
    public Audio loadAudio(String pathName)
    {
	String[] filePathArray = pathName.split("/");
	String fileName = filePathArray[filePathArray.length - 1];

	String[] fileNameArray = fileName.split("\\.");
	String name = fileNameArray[0];

	if (mAudioHashMap.containsKey(name))
	{
	    return mAudioHashMap.get(name);
	}

	Audio audio = getAudioFromAsset(pathName, name);

	if (audio != null)
	{
	    mAudioHashMap.put(name, audio);
	}

	return audio;
    }

    private Audio getAudioFromAsset(String pathName, String name)
    {
	try
	{
	    AssetFileDescriptor afd = mAssetManager.openFd(pathName);
	    MediaPlayer player = new MediaPlayer();
	    player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
		    afd.getLength());
	    player.prepare();

	    return new Audio(name, player);
	}
	catch (IOException e)
	{
	    e.printStackTrace();
	}

	return null;
    }

    @Override
    public Audio get(String name)
    {
	return mAudioHashMap.get(name);
    }

    @Override
    public void remove(String name)
    {
	mAudioHashMap.remove(name);
    }

    @Override
    public void remove(Audio object)
    {
	mAudioHashMap.remove(object);
    }

    @Override
    public void dispose()
    {
	for (Audio value : mAudioHashMap.values())
	{
	    value.stop();
	    value.release();
	}

	mAudioHashMap.clear();

	mAudioHashMap = null;
	mInstance = null;
    }
}
